package com.cd.university.controller;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.utils.IOUtils;
import com.cd.university.common.RestResult;
import com.cd.university.config.security.authentication.util.SecurityThreadLocal;
import com.cd.university.config.security.authentication.util.ThreadLocalUser;
import com.cd.university.controller.form.*;
import com.cd.university.db.pojo.User;
import com.cd.university.service.RoleService;
import com.cd.university.service.UserService;
import com.cd.university.vo.UserVo;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.*;
import java.util.Collection;
import java.util.Map;

/**
 * scientific_management_development_environment
 * @author 陈栋
 * @create 2021/9/3 18:59
 */
@RestController
@Api("用户接口")
@RequestMapping("/user")
public class UserController {

    /**
     * spring security会把当前的请求，缓存到HttpSessionRequestCache这里面去
     */
    private RequestCache requestCache = new HttpSessionRequestCache();

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    /**
     * 当没有进行身份认证的时候跳转到这里
     * @param request 请求和响应都放在里面
     * @return 返回自定义对象
     */
    @RequestMapping("/require")
    @ResponseStatus(code = HttpStatus.UNAUTHORIZED)
    public RestResult requireAuthentication (ServletWebRequest request) {

        // 拿到缓存里面的内容
        SavedRequest savedRequest = requestCache.getRequest(request.getRequest(), request.getResponse());
        if (savedRequest!=null) {
            // 实际上是引发跳转的url
//            String targetUrl = savedRequest.getRedirectUrl();
//            logger.info("没有进行登录访问的url为："+savedRequest.getRedirectUrl());
        }
        return RestResult.failure(HttpStatus.UNAUTHORIZED.value(),"需要进行身份认证，请回到登录页进行身份认证");
    }

    @PostMapping("/register")
    @ApiOperation("用户注册")
    public RestResult registerUser(@Valid @RequestBody UserRegisterForm form) {
        return userService.registerUser(form);
    }

    @GetMapping("/")
    @ApiOperation("获得登录的用户信息")
    public RestResult getOnUserInfo() {
        String name = SecurityContextHolder.getContext().getAuthentication().getName();
        User user = userService.searchUserByUserInfo(name);

        user.setPassword("Invisible");
        return RestResult.success("用户信息")
                .put("data",userService.searchUserByUserInfo(name));
    }

    @GetMapping("/getuser/{username}")
    @ApiOperation("根据用户id获得用户")
    @PreAuthorize("hasAuthority('编辑用户信息')")
    public RestResult getUserByUserId(@PathVariable String username) {
        User user = userService.searchUserByUserInfo(username);
        String roleName = roleService.searchRoleName(user.getRoleId());

        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user, userVo);
        userVo.setRoleName(roleName);

        return RestResult.success("用户信息")
                .put("data",userVo);
    }

    @GetMapping("/getUsers")
    @ApiOperation("获得所有的用户")
    public RestResult getAllUsers() {
        return RestResult.success("所有的用户信息")
                .put("data",userService.searchAllUser());
    }


    @PostMapping("/updateUserRole")
    @ApiOperation("修改用户的角色")
    @PreAuthorize("hasAnyAuthority('管理角色','超级管理员')")
    public RestResult updateUserRole(@Valid @RequestBody UserRoleIdForm form) {
        Collection<? extends GrantedAuthority> authorities =
                SecurityContextHolder.getContext().getAuthentication().getAuthorities();
        try {
            int row = userService.updateUserRole(form.getUserId(), form.getRoleId());
            if (row>0) {
                return RestResult.success("修改用户角色成功");
            }else {
                return RestResult.failure("修改用户角色失败");
            }
        }catch (Exception e) {
            return RestResult.failure("修改用户角色失败");
        }
    }

    @GetMapping("/delete")
    @ApiOperation("删除用户")
    @PreAuthorize("hasAnyAuthority('超级管理员')")
    public RestResult deleteUserByUserId(@RequestParam Integer userId) {
        try {
            int row = userService.deleteUserByUserId(userId);

            if (row>0) {
                return RestResult.success("删除用户成功");
            }else {
                return RestResult.failure("不存在该用户");
            }
        }catch (Exception e) {
            e.printStackTrace();
            return RestResult.failure("删除用户失败");
        }
    }

    @PostMapping("/update")
    @ApiOperation("修改个人信息")
    public RestResult updateUserInfo(@Valid @RequestBody UserForm form) {

        try {
            int row = userService.updateUserInfo(form);

            if (row>0) {
                form.setPassword("Invisible");
                return RestResult.success("用户信息修改成功").put("data",form);
            }else {
                return RestResult.failure("改用户信息不存在");
            }
        }catch (Exception e) {
            e.printStackTrace();
            return RestResult.failure("用户信息修改失败");
        }
    }

    @PostMapping("/image")
    @ApiOperation("上传用户的头像")
    public RestResult updateUserImage(@RequestParam("file") MultipartFile image) {
        return userService.updateUserImage(image);
    }


    @GetMapping("/searchByUserNumber")
    @ApiOperation("按照用户的编号进行搜索")
    public RestResult searchByUserNumber(@RequestParam("userNumber") String userNumber) {
        return userService.searchUserByUserNumber(userNumber);
    }

    @GetMapping("/getImage")
    @ApiOperation("获取到用户的头像")
    public RestResult getUserImage(HttpServletRequest request,
                                   @RequestParam("userId") Integer userId,
                                   HttpServletResponse response) {
        return userService.getUserImage(response,request,userId);
    }

    @PostMapping("/updateBasicInfo")
    @ApiOperation("修改用户的基本数据")
    public RestResult updateBasicInfo(@Valid @RequestBody UserBasicInfoForm form) {
        return userService.updateBasicInfo(form);
    }

    @PostMapping("/updatePwd")
    @ApiOperation("通过手机验证码修改密码")
    public RestResult updatePwd(@Valid @RequestBody UserPasswordForm form) {
        return userService.updatePwd(form);
    }

    @PostMapping("/retrievePassword")
    @ApiOperation("通过电话验证码修改密码")
    public RestResult userRetrievePassword() {
        String smsCode = SecurityThreadLocal.getValidateCodeThreadLocal().get();
        ThreadLocalUser localUser = SecurityThreadLocal.getInstance().get();
        UserRetrievePwdBySmsForm form = new UserRetrievePwdBySmsForm(localUser.getMobile(), smsCode, localUser.getPassword());
        return userService.userRetrievePassword(form);
    }

    @GetMapping("/confirmNewUser")
    @ApiOperation("确认该用户已经查询新手指导")
    public RestResult confirmNewUser(@RequestParam(required = true) Integer userId) {
        return userService.confirmNewUser(userId);
    }

    @GetMapping("/generateSuperCode")
    @ApiOperation("生成超级管理员的邀请码")
    @PreAuthorize("hasAnyAuthority('超级管理员')")
    public RestResult GenerateSuperInvitationCode(@RequestParam Integer userId) {
        return userService.GenerateSuperInvitationCode(userId);
    }

    @GetMapping("/becomeAdmin")
    @ApiOperation("成为超级管理员")
    public RestResult VerifyInvitationCodeAndChangeRole(@RequestParam Integer userId,
                                                        @RequestParam String code) {
        return userService.VerifyInvitationCodeAndChangeRole(userId, code);
    }

}
